import { $, cd, chalk, fs, path, within } from 'zx';
import compressing from 'compressing';

/**
 * 输入脚本的log信息
 * @param p
 * @returns {Promise<void>}
 */
export async function stdout(p) {
  for await (const chunk of p.stdout) {
    console.log(chalk.bgGreen.greenBright(chunk));
  }
}

/**
 * 判断是否存在 package.json 并安全的执行回调
 * @param dir
 * @param callback
 * @returns {Promise<void>}
 */
export async function existPackageJson(dir, callback) {
  const packageJsonPath = path.resolve(dir, 'package.json');

  if (fs.existsSync(packageJsonPath)) {
    try {
      callback && await callback(packageJsonPath);
    } catch (e) {
      console.log(chalk.red(e.message));
    }
  }
}

/**
 * 打包项目成 tgz 压缩包
 * @param dirs
 * @param outDir
 * @param version
 * @param projectNames
 * @returns {Promise<void>}
 */
export async function packPackages(dirs, outDir, version = null, projectNames = []) {
  const packagePath = dirs;
  for (const fileName of fs.readdirSync(packagePath)) {
    // 如果指定發佈某個包
    if (projectNames.length && !projectNames.includes(fileName)) continue;
    const projectPath = path.resolve(packagePath, fileName);

    // 打包 template 文件
    await within(async () => {
      await existPackageJson(projectPath, async (packageJsonPath) => {
        if (version) {
          console.log(chalk.yellow(`<${fileName}> 修改 package.json 中的版本号`));
          const oldPackageJson = fs.readJsonSync(packageJsonPath);
          fs.writeJsonSync(packageJsonPath, { ...oldPackageJson, version}, { spaces: 2 });
        }

        console.log(chalk.blue(`<${fileName}> 正在打包`));
        await cd(projectPath);
        await stdout($`pnpm pack --out="${outDir}/${fileName}.tgz"`);
      })
    })
  }
}

/**
 * 压缩 | 解压包
 * @param dirs
 * @param outDir
 * @param type
 * @param projectNames
 * @returns {Promise<void>}
 */
export async function tarPackages(dirs, outDir, type = 'extract', projectNames = []) {
  const isPack = type === 'pack';
  if (!fs.existsSync(dirs)) return;

  for (const fileName of fs.readdirSync(dirs)) {
    // 如果指定發佈某個包
    if (projectNames.length && !projectNames.includes(fileName)) continue;

    const projectPath = path.resolve(dirs, fileName);

    if (isPack) {
      console.log(chalk.bgBlue(`<${fileName}> 正在压缩`));

      await compressing.tgz.compressDir(projectPath, outDir)
    } else {
      console.log(chalk.bgBlue(`<${fileName}> 正在解压缩`));

      await compressing.tgz.uncompress(projectPath, path.resolve(outDir, fileName.split('.').slice(0, -1).join('.')));
    }
  }
}
